package com.taotao.wechat.business;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.rop.client.CompositeResponse;
import com.taotao.admin.MyRopClient;
import com.taotao.rop.database.Constant;
import com.taotao.rop.database.domain.WechatResp;
import com.taotao.rop.response.BaseResponse;
import com.taotao.rop.service.RespSearchService;
import com.taotao.rop.util.DateTimeUtil;
import com.taotao.wechat.game.*;
import com.taotao.wechat.message.MessageEntry;
import com.taotao.wechat.message.resp.Article;
import com.taotao.wechat.message.resp.BaseMessage;
import com.taotao.wechat.message.resp.NewsMessage;
import com.taotao.wechat.message.resp.TextMessage;
import com.taotao.wechat.util.MessageUtil;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import org.springframework.web.client.RestTemplate;

import java.io.IOException;
import java.util.*;

/**
 * 文本匹配
 */
public class TextRecognition {
    private static Logger logger = Logger.getLogger(TextRecognition.class);
    private static final String error_message = "请求处理异常，请稍候尝试！";
    private static final String no_message = "无数据";
    public static final Integer max_resps = 3;

    public static String textRecognition(BaseMessage baseMessage, String content, String appKey){
        return textRecognition(baseMessage, content, appKey, "");
    }

    public static String textRecognition(BaseMessage baseMessage, String content, String appKey, String type){
        if (content.equals("查询")) {
            content = "1";
        } else if (content.equals("办理")) {
            content = "2";
        } else if (content.equals("服务")) {
            content = "3";
        } else if (content.equalsIgnoreCase("4G")) {
            content = "4";
        } else if (content.equals("资费") || content.equals("品牌")) {
            content = "5";
        } else if (content.equals("活动")) {
            content = "6";
        }

        if (FlopGame.IS_ENABLE) {
            String result = new FlopGame(baseMessage, content, appKey).playOne();
            if (StringUtils.isNotBlank(result)) {
                return result;
            }
        }

        if (FindWordGame1.IS_ENABLE) {
            FindWordGame1 findWordGame1 = new FindWordGame1(baseMessage, content, appKey);
            Date now = new Date();
            if (DateTimeUtil.compareDate(findWordGame1.getEndDate(), now) == -1) {
                //游戏一活动结束，开始游戏二
                if (FindWordGame2.IS_ENABLE) {
                    FindWordGame2 findWordGame2 = new FindWordGame2(baseMessage, content, appKey);
                    String result;
                    if (DateTimeUtil.compareDate(findWordGame2.getEndDate(), now) == 1) {
                        result = findWordGame2.playOne();
                    } else {
                        //游戏已经结束
                        result = findWordGame2.queryPrize();
                    }
                    if (StringUtils.isNotBlank(result)) {
                        return result;
                    }
                }
            } else {
                //开始游戏一
                String result = findWordGame1.playOne();
                if (StringUtils.isNotBlank(result)) {
                    return result;
                }
            }
        }

        if (Wxcs.IS_ENABLE) {
            Wxcs wxcs = new Wxcs(baseMessage, content, appKey);
            String result = wxcs.playTwo();
            if (StringUtils.isNotBlank(result)) {
                return result;
            }
        }

        if (FirstFocusGame.IS_ENABLE) {
            FirstFocusGame firstFocusGame = new FirstFocusGame(baseMessage, content, appKey);
            String result = firstFocusGame.playOne();
            if (StringUtils.isNotBlank(result)) {
                return result;
            }
        }

        if (FirstFocusGame1.IS_ENABLE) {
            FirstFocusGame1 firstFocusGame1 = new FirstFocusGame1(baseMessage, content, appKey);
            String result = firstFocusGame1.playOne();
            if (StringUtils.isNotBlank(result)) {
                return result;
            }
        }

        if (WheelGame.IS_ENABLE) {
            WheelGame wheelGame = new WheelGame(baseMessage, content, appKey);
            String result = wheelGame.playOne();
            if (StringUtils.isNotBlank(result)) {
                return result;
            }
        }

        if (WheelGame2.IS_ENABLE) {
            WheelGame2 wheelGame2 = new WheelGame2(baseMessage, content, appKey);
            String result = wheelGame2.playOne();
            if (StringUtils.isNotBlank(result)) {
                return result;
            }
        }

        if (ShareOneImage.IS_ENABLE) {
            ShareOneImage shareOneImage = new ShareOneImage(baseMessage, content, appKey);
//            String result = shareOneImage.playThree();
            String result = shareOneImage.queryPrize();
            if (StringUtils.isNotBlank(result)) {
                return result;
            }
        }

        if (SlotGame.IS_ENABLE) {
            SlotGame slotGame = new SlotGame(baseMessage, content, appKey);
            String result = slotGame.playOne();
            if (StringUtils.isNotBlank(result)) {
                return result;
            }
        }

        //如果查询关键值得到结果，直接返回
        String resp = getRespByKeyvalue(baseMessage, content, appKey);
        if (resp != null && resp.length() > 0) {
            return resp;
        }

        //模糊匹配
        List<WechatResp> wechatResps = RespSearchService.getInstance().searchIndex(content, Constant.priority_high, appKey, max_resps);
        if (wechatResps.size() == 0){
            wechatResps.addAll(RespSearchService.getInstance().searchIndex(content, Constant.priority_middle, appKey, max_resps-wechatResps.size()));
        }
        if (wechatResps.size() == 0) {
            wechatResps.addAll(RespSearchService.getInstance().searchIndex(content, Constant.priority_low, appKey, max_resps - wechatResps.size()));
        }
        //如果只有一条且为图文消息，则返回图文消息
        if (wechatResps.size() == 1 && wechatResps.get(0).getMsgType().equalsIgnoreCase("news")) {
            return getRespByKeyvalue(baseMessage, wechatResps.get(0).getKeyvalue(), appKey);
        }

        //如果多于一条，把图文消息的title作为文本消息，和其他文本消息组成列表返回
        StringBuilder sb = new StringBuilder();
        String voiceStr = "";
        if (type.equalsIgnoreCase(MessageUtil.REQ_MESSAGE_TYPE_VOICE)){
            voiceStr = "识别出您的语音：".concat(content).concat("\n");
            sb.append(voiceStr);
        }
        if (wechatResps.size() > 1) {
            sb.append("亲~ 请回复序号选择以下业务：\n");
        }
        for (WechatResp wechatResp : wechatResps) {
            StringBuilder oneResp = new StringBuilder();
            if (wechatResp.getKeyvalue() != null) {
                oneResp.append(wechatResp.getKeyvalue().concat("、"));
            }
            if (wechatResp.getMsgType().equalsIgnoreCase("text")) {
                oneResp.append(wechatResp.getContent().replace("\\n", "\n").concat("\n"));
            } else if (wechatResp.getMsgType().equalsIgnoreCase("news")) {
                oneResp.append(wechatResp.getTitle().replace("\\n", "\n").concat("\n"));
            }
            if (oneResp.length() + sb.length() > 900) {
                break;
            } else {
                sb.append(oneResp);
            }
        }

        //未匹配任何信息，返回默认应答
        if (StringUtils.isEmpty(sb.toString())) {
            return getRespByKeyvalue(baseMessage, "default", appKey);
        } else if (!StringUtils.isEmpty(voiceStr) && voiceStr.equals(sb.toString())) {
            //语音未被识别时，返回带语音字符串的默认应答
            return getRespByKeyvalue(voiceStr, baseMessage, "default", appKey);
        }

        TextMessage textMessage = new TextMessage(baseMessage);
        textMessage.setContent(sb.toString());
        return MessageUtil.textMessageToXml(textMessage);
    }

    private static String getRespByKeyvalue(String voiceStr, BaseMessage baseMessage, String keyvalue, String appKey){
        String respStr = "";
        WechatResp resp = new WechatResp();
        resp.setKeyvalue(keyvalue);
        resp.setAppId(appKey);
        resp.setStatus(Constant.STATUS_ENABLE);

        CompositeResponse<BaseResponse> response = MyRopClient.getRopClient("").buildClientRequest()
                .post(resp, BaseResponse.class, "wechatResp.searchByKeyvalue", "1.0");
        if (response.isSuccessful()){
            BaseResponse baseResponse = response.getSuccessResponse();
            if (baseResponse.getSuccess()) {
                LinkedHashMap<String, Object> dataMap = (LinkedHashMap<String, Object>) baseResponse.getData();
                if (dataMap.get("msgType") != null) {
                    String msgType = dataMap.get("msgType").toString();
                    if (msgType.equalsIgnoreCase("text")) {
                        TextMessage textMessage = new TextMessage(baseMessage);
                        textMessage.setMsgType(msgType);
                        textMessage.setContent(voiceStr + dataMap.get("content").toString().replace("\\n", "\n"));
                        respStr = MessageUtil.textMessageToXml(textMessage);
                    } else if (msgType.equalsIgnoreCase("news")) {
                        NewsMessage newsMessage = new NewsMessage(baseMessage);
                        newsMessage.setMsgType("news");
                        List<Article> respArticles = new ArrayList<Article>();

                        //获取主图文
                        List<LinkedHashMap<String, Object>> articles = (List<LinkedHashMap<String, Object>>) dataMap.get("articleList");
                        for (LinkedHashMap<String, Object> article : articles) {
                            Article theArticle = new Article();
                            theArticle.setTitle(article.get("title").toString().replace("\\n", "\n"));
                            if (article.get("description") != null) {
                                theArticle.setDescription(article.get("description").toString().replace("\\n", "\n"));
                            }
                            if (article.get("picUrl") != null) {
                                theArticle.setPicUrl(MyRopClient.BASE_URL + "/" + article.get("picUrl").toString());
                            }
                            theArticle.setUrl(article.get("url").toString());
                            respArticles.add(theArticle);

                            //获取子图文
                            List<LinkedHashMap<String, Object>> subArticles = (List<LinkedHashMap<String, Object>>) article.get("subArticleList");
                            if (subArticles != null) {
                                for (LinkedHashMap<String, Object> subArticle : subArticles) {
                                    Article theSubArticle = new Article();
                                    theSubArticle.setTitle(subArticle.get("title").toString().replace("\\n", "\n"));
                                    if (subArticle.get("description") != null) {
                                        theSubArticle.setDescription(subArticle.get("description").toString().replace("\\n", "\n"));
                                    }
                                    if (subArticle.get("picUrl") != null) {
                                        theSubArticle.setPicUrl(MyRopClient.BASE_URL + "/" + subArticle.get("picUrl").toString());
                                    }
                                    theSubArticle.setUrl(subArticle.get("url").toString());
                                    respArticles.add(theSubArticle);
                                }
                            }
                        }
                        newsMessage.setArticleCount(respArticles.size());
                        newsMessage.setArticles(respArticles);
                        respStr = MessageUtil.newsMessageToXml(newsMessage);
                    }
                }
            } else {
                TextMessage textMessage = new TextMessage(baseMessage);
                textMessage.setContent(voiceStr + baseResponse.getMsg());
                respStr = MessageUtil.textMessageToXml(textMessage);
            }
        } else {
            TextMessage textMessage = new TextMessage(baseMessage);
            textMessage.setContent(error_message);
            respStr = MessageUtil.textMessageToXml(textMessage);
        }
        return respStr;
    }

    /**
     * 根据关键值获取单条响应消息
     * @param keyvalue 关键值
     * @param appKey 微信公众号id
     * @return 响应消息
     */
    private static String getRespByKeyvalue(BaseMessage baseMessage, String keyvalue, String appKey){
        return getRespByKeyvalue("", baseMessage, keyvalue, appKey);
    }

    private static final String serviceMapAk = "TlHveAOpjb1jkv0GxUs4MSBs";
    private static final String queryKey = "中国移动";
    public static String getRespByLocation(BaseMessage baseMessage, Map<String, String> requestMap) throws IOException {
        String locationX = requestMap.get(MessageEntry.Location_X);
        String locationY = requestMap.get(MessageEntry.Location_Y);
        String scale = requestMap.get(MessageEntry.Scale);
        String label = requestMap.get(MessageEntry.Label);
        String googleToBaidu = "http://api.map.baidu.com/ag/coord/convert?from=2&to=4&x=" + locationX + "&y=" + locationY;//google 坐标转化为百度坐标
        RestTemplate restTemplate = new RestTemplate();
        String resultStr = restTemplate.getForObject(googleToBaidu, String.class);
        logger.info("convert to baidu:" + resultStr);
        ObjectMapper objectMapper = new ObjectMapper();
        LinkedHashMap result = objectMapper.readValue(resultStr, LinkedHashMap.class);
        //百度api转化坐标后，得到base64字符串，需要转化
        String latx = new String(Base64.decodeBase64(result.get("x").toString()));
        String lgty = new String(Base64.decodeBase64(result.get("y").toString()));

        //通过百度地图api搜索
        String url = "http://api.map.baidu.com/place/v2/search?ak=" + serviceMapAk + "&output=json&query=" + queryKey + "&page_size=5&page_num=0&scope=2&location=" + latx + "," + lgty + "&radius=2000&filter=sort_name:distance";
        resultStr = restTemplate.getForObject(url, String.class);
        logger.info("baidu search:" + resultStr);
        result = objectMapper.readValue(resultStr, LinkedHashMap.class);

        NewsMessage newsMessage = new NewsMessage(baseMessage);
        newsMessage.setMsgType("news");
        if (Integer.parseInt(result.get("status").toString()) == 0
                && result.get("message").toString().equalsIgnoreCase("ok")) {
            List<LinkedHashMap<String, Object>> results = (List<LinkedHashMap<String, Object>>) result.get("results");
            if (results != null) {
                List<Article> articles = new ArrayList<Article>();
                for (int i = 0; i < results.size(); i++) {
                    LinkedHashMap<String, Object> resultMap = results.get(i);
                    Article article = new Article();
                    //拼图文消息的title和description
                    StringBuilder sb = new StringBuilder(resultMap.get("name") + " 距离约");
                    LinkedHashMap<String, Object> detail_info = (LinkedHashMap<String, Object>) resultMap.get("detail_info");
                    if (detail_info != null) {
                        sb.append(detail_info.get("distance")  + "米" );
                    }
                    article.setTitle(sb.toString());
                    article.setDescription(sb.toString());
                    sb.delete(0, sb.length());

                    //拼图文消息的url
                    sb.append(MyRopClient.BASE_URL + "/BaiDuMap/BaiDuMap.htm?lat=" + latx + "&lgt=" + lgty + "&lat2=");
                    LinkedHashMap<String, Object> location = (LinkedHashMap<String, Object>) resultMap.get("location");
                    if (location != null) {
                        sb.append(location.get("lat") + "&lgt2=" + location.get("lng"));
                    }
                    article.setUrl(sb.toString());
                    sb.delete(0, sb.length());

                    //设置图文消息的picUrl
                    sb.append(MyRopClient.BASE_URL + "/BaiDuMap/img/");
                    if (i == 0) {
                        sb.append("mapbig.png");
                    } else {
                        sb.append("mapsmall.png");
                    }
                    article.setPicUrl(sb.toString());

                    articles.add(article);
                }
                newsMessage.setArticles(articles);
                newsMessage.setArticleCount(articles.size());
            }
        }
        return MessageUtil.newsMessageToXml(newsMessage);
    }

    public static void main(String[] args) {
//        String s2 = TextRecognition.getRespByKeyvalue(new BaseMessage(), "nmg47", "wx77ae5030ce533f0c");
//        String s3 = TextRecognition.getRespByKeyvalue(new BaseMessage(), "text", "wxb55a7b803bca8279");
//        Map<String, String> requestMap = new LinkedHashMap<String, String>();
//        requestMap.put(MessageEntry.Location_X, "40.821945");
//        requestMap.put(MessageEntry.Location_Y, "111.759346");
//        String s4 = null;
//        try {
//            s4 = TextRecognition.getRespByLocation(new BaseMessage(), requestMap);
//        } catch (IOException e) {
//            e.printStackTrace();
//        }
//        System.out.println(s4);
//        System.out.println(s2);
//        System.out.println(s3);

        BaseMessage baseMessage = new BaseMessage();
        baseMessage.setToUserName("aaabb");
        baseMessage.setFromUserName("gh_999");
//        String s1 = TextRecognition.textRecognition(baseMessage, "15311112222", "wx8010a0acb61a2948");
        String s1 = TextRecognition.textRecognition(baseMessage, "15311112226", "wx8010a0acb61a2948");
//        String s3 = TextRecognition.textRecognition(baseMessage, "15134707533", "wxbb9311109208320a");
        System.out.println(s1);
//        baseMessage.setMsgType(MessageUtil.REQ_MESSAGE_TYPE_IMAGE);
//        String s2 = TextRecognition.textRecognition(baseMessage, "http://www.aihami.com/uploads/allimg/150202/166-15020214011G30.jpg", "wx8010a0acb61a2948");
//        System.out.println(s2);
////        baseMessage.setMsgType(MessageUtil.REQ_MESSAGE_TYPE_IMAGE);
//        String s1 = TextRecognition.textRecognition(baseMessage, "http://www.baidu.com/img/bdlogo.png", "wx8010a0acb61a2948");
//        String s1 = TextRecognition.textRecognition(baseMessage, "15024961340", "wx8010a0acb61a2948");
//        String s1 = TextRecognition.textRecognition(baseMessage, "csdm", "33");
//        String s1 = TextRecognition.textRecognition(baseMessage, "流量", "wx8010a0acb61a2948", MessageUtil.REQ_MESSAGE_TYPE_VOICE);
//        System.out.println(s1);
    }
}
